
// const Excel = require('exceljs')
import * as Excel from 'exceljs'
// import FileSaver from 'file-saver'
var exportExcel = function(luckysheets, value) {
  console.log(luckysheets)
  // 1.创建工作簿，可以为工作簿添加属性
  const workbook = new Excel.Workbook()
  // 2.创建表格，第二个参数可以配置创建什么样的工作表
  luckysheets.forEach(function(table) {
    // console.log(table)
    if (table.celldata.length === 0) return true
    const worksheet = workbook.addWorksheet(table.name)
    if (table.defaultColWidth) {
      worksheet.properties.defaultColWidth = (table.defaultColWidth - 5) / 8 + 0.83
    }
    if (table.defaultRowHeight) {
      worksheet.properties.defaultRowHeight = table.defaultRowHeight * 72 / 96
    }
    const config = table.config || {}
    const merge = (config && config.merge) || {}
    const borderInfo = (config && config.borderInfo) || {}
    const columnlen = (config && config.columnlen) || {}
    const rowlen = (config && config.rowlen) || {}
    // 3.设置单元格合并,设置单元格边框,设置单元格样式,设置值,导出图片
    setStyleAndValue(table.celldata, worksheet)
    setHidden(config, worksheet)
    setColumnlen(columnlen, worksheet)
    setRowlen(rowlen, worksheet)
    setMerge(merge, worksheet)
    setBorder(borderInfo, worksheet)
    setImages(table.images, worksheet, workbook)
    return true
  })

  // 4.写入 buffer
  return workbook.xlsx.writeBuffer().then(data => {
    const blob = new Blob([data], {
      type: 'application/vnd.ms-excel;charset=utf-8'
    })
    return blob
    // console.log('导出成功！')
    // FileSaver.saveAs(blob, `${value}.xlsx`)
  })
}
const fontConvert = function({ ff = 0, fc = '#000000', bl = 0, it = 0, fs = 10, cl = 0, ul = 0, vt = 0 }) {
  // 如果字体颜色色为rgb格式需转换
  let fontColor = fc;
  if (fontColor.indexOf('rgb') !== -1) {
    fontColor = colorRGBtoHex(fontColor)
  }

  // 出现Bug，导入的时候ff为luckyToExcel的val
  const font = {
    name: typeof ff === 'number' ? luckyToExcelFont[ff] : ff,
    family: ff,
    size: fs,
    color: { argb: fontColor.replace('#', '') },
    bold: luckyToExcelFont.num2bl(bl),
    italic: luckyToExcelFont.num2bl(it),
    underline: luckyToExcelFont.num2bl(ul),
    strike: luckyToExcelFont.num2bl(cl)
  }
  if (vt !== 0) {
    font.vertAlign = vt === 1 ? 'superscript' : 'subscript'
  }
  return font
}

const setStyleAndValue = function(celldata, worksheet) {
  celldata.forEach(cell => {
    const r = cell.r
    const c = cell.c
    const v = cell.v
    //  style 填入到_value中可以实现填充色
    const letter = createCellPos(c)
    const target = worksheet.getCell(letter + (r + 1))
    let value = ''
    if (v) {
      if (v.f) {
        value = { formula: v.f.replace('=', ''), result: v.v }
      } else if (!v.v && v.ct && v.ct.s) {
        // xls转为xlsx之后，内部存在不同的格式，都会进到富文本里，即值不存在与cell.v，而是存在于cell.ct.s之后
        // value = cell.ct.s[0].v
        v.ct.s.forEach(arr => {
          value += arr.v
        })
      } else {
        value = v.v
      }
      if (v && v.ct && v.ct.fa) {
        target.numFmt = v.ct.fa
      }
      if (v.bg) {
        let bgColor = v.bg;
        // console.log(bgColor)
        // 如果背景色为rgb格式需转换
        if (bgColor.indexOf('rgb') !== -1) {
          bgColor = colorRGBtoHex(bgColor)
        }

        target.fill = {
          type: 'pattern',
          pattern: 'solid',
          fgColor: { argb: bgColor.replace('#', '') }
        }
      }
    }
    target.font = fontConvert(v || {})
    target.alignment = alignmentConvert(v || {})
    target.value = value
  })
}
const borderConvert = function(borderType, style = 1, color = '#000') {
  let bordeColor = color;
  // 如果颜色为rgb格式需转换
  if (bordeColor.indexOf('rgb') !== -1) {
    bordeColor = colorRGBtoHex(bordeColor)
  }

  // 对应luckysheet的config中borderinfo的的参数
  if (!borderType) {
    return {}
  }
  const template = {
    style: luckyToExcelBorderRange.style[style],
    color: { argb: bordeColor.replace('#', '') }
  }
  const border = {}
  if (luckyToExcelBorderRange.type[borderType] === 'all') {
    border['top'] = template
    border['right'] = template
    border['bottom'] = template
    border['left'] = template
  } else {
    border[luckyToExcelBorderRange.type[borderType]] = template
  }
  return border
}
const setBorder = function(luckyBorderInfo, worksheet) {
  if (!Array.isArray(luckyBorderInfo)) return
  luckyBorderInfo.forEach(function(elem) {
    // 现在只兼容到borderType 为range的情况
    if (elem.rangeType === 'range') {
      const border = borderConvert(elem.borderType, elem.style, elem.color)
      const rang = elem.range[0]
      const row = rang.row
      const column = rang.column
      for (let i = row[0] + 1; i < row[1] + 2; i++) {
        for (let y = column[0] + 1; y < column[1] + 2; y++) {
          worksheet.getCell(i, y).border = border
        }
      }
    }
    if (elem.rangeType === 'cell') {
      // eslint-disable-next-line camelcase
      const { col_index, row_index } = elem.value
      const borderData = Object.assign({}, elem.value)
      delete borderData.col_index
      delete borderData.row_index
      // eslint-disable-next-line camelcase
      worksheet.getCell(row_index + 1, col_index + 1).border = addBorderToCell(borderData, row_index, col_index)
    }
  })
}
const setImages = function(imagesArr, worksheet, workbook) {
  if (typeof imagesArr !== 'object') return
  for (const key in imagesArr) {
    // console.log(imagesArr[key]);
    // 通过 base64  将图像添加到工作簿
    const myBase64Image = imagesArr[key].src
    // 开始行 开始列 结束行 结束列
    const start = { col: imagesArr[key].fromCol, row: imagesArr[key].fromRow }
    const end = { col: imagesArr[key].toCol, row: imagesArr[key].toRow }
    const imageId = workbook.addImage({
      base64: myBase64Image,
      extension: 'png'
    })
    worksheet.addImage(imageId, {
      tl: start,
      br: end,
      editAs: 'oneCell'
    })
  }
}
const setMerge = function(luckyMerge = {}, worksheet) {
  const mergearr = Object.values(luckyMerge)
  mergearr.forEach(function(elem) {
    // elem格式：{r: 0, c: 0, rs: 1, cs: 2}
    // 按开始行，开始列，结束行，结束列合并（相当于 K10:M12）
    worksheet.mergeCells(
      elem.r + 1,
      elem.c + 1,
      elem.r + elem.rs,
      elem.c + elem.cs
    )
  })
}
const setRowlen = function(rowlen, worksheet) {
  Object.keys(rowlen).forEach(rowIndex => {
    const rowNo = parseInt(rowIndex) + 1
    const row = worksheet.getRow(rowNo)
    const len = rowlen[rowIndex]
    if (row && len) {
      row.height = len * 72 / 96
    }
  })
}

// eslint-disable-next-line no-unused-vars
const setColumnlen = function(columnlen, worksheet) {
  Object.keys(columnlen).forEach(colIndex => {
    const colNo = parseInt(colIndex) + 1
    const col = worksheet.getColumn(colNo)
    const len = columnlen[colIndex]
    if (col && len) {
      col.width = (len - 5) / 8
    }
  })
}

const setHidden = function(config, worksheet) {
  if (config) {
    const { rowhidden, colhidden } = config
    if (rowhidden) {
      Object.keys(rowhidden).forEach(rowNoNum => {
        const rowNo = parseInt(rowNoNum) + 1
        const row = worksheet.getRow(rowNo)
        if (row) {
          row.hidden = true
        }
      })
    }
    if (colhidden) {
      Object.keys(colhidden).forEach(colNoNum => {
        const colNo = parseInt(colNoNum) + 1
        const col = worksheet.getColumn(colNo)
        if (col) {
          col.hidden = true
        }
      })
    }
  }
}

// luckysheet：ff(样式), fc(颜色), bl(粗体), it(斜体), fs(大小), cl(删除线), ul(下划线)
const luckyToExcelFont = {
  0: 'Times New Roman',
  1: 'Arial',
  2: 'Tahoma',
  3: 'Verdana',
  4: '微软雅黑',
  5: '宋体（Song）',
  6: '黑体（ST Heiti）',
  7: '楷体（ST Kaiti）',
  8: '仿宋（ST FangSong）',
  9: '新宋体（ST Song）',
  10: '华文新魏',
  11: '华文行楷',
  12: '华文隶书',
  num2bl: function(num) {
    return num !== 0
  }
}

// luckysheet:vt(垂直), ht(水平), tb(换行), tr(旋转)
const luckyToExcelAlignment = {
  vertical: {
    0: 'middle',
    1: 'top',
    2: 'bottom',
    default: 'top'
  },
  horizontal: {
    0: 'center',
    1: 'left',
    2: 'right',
    default: 'left'
  },
  wrapText: {
    0: false,
    1: false,
    2: true,
    default: false
  },
  textRotation: {
    0: 0,
    1: 45,
    2: -45,
    3: 'vertical',
    4: 90,
    5: -90,
    default: 0
  }
}
const alignmentConvert = function({ vt = 'default', ht = 'default', tb = 'default', tr = 'default' }) {
  return {
    vertical: luckyToExcelAlignment.vertical[vt],
    horizontal: luckyToExcelAlignment.horizontal[ht],
    wrapText: luckyToExcelAlignment.wrapText[tb],
    textRotation: luckyToExcelAlignment.textRotation[tr]
  }
}
const luckyToExcelBorderRange = {
  type: {
    'border-all': 'all',
    'border-top': 'top',
    'border-right': 'right',
    'border-bottom': 'bottom',
    'border-left': 'left'
  },
  style: {
    0: 'none',
    1: 'thin',
    2: 'hair',
    3: 'dotted',
    4: 'dashDot', // 'Dashed',
    5: 'dashDot',
    6: 'dashDotDot',
    7: 'double',
    8: 'medium',
    9: 'mediumDashed',
    10: 'mediumDashDot',
    11: 'mediumDashDotDot',
    12: 'slantDashDot',
    13: 'thick'
  }
}

const luckyToExcelBorderCell = {
  type: {
    l: 'left',
    r: 'right',
    b: 'bottom',
    t: 'top'
  },
  style: {
    0: 'none',
    1: 'thin',
    2: 'hair',
    3: 'dotted',
    4: 'dashDot', // 'Dashed',
    5: 'dashDot',
    6: 'dashDotDot',
    7: 'double',
    8: 'medium',
    9: 'mediumDashed',
    10: 'mediumDashDot',
    11: 'mediumDashDotDot',
    12: 'slantDashDot',
    13: 'thick'
  }
}

function addBorderToCell(borders) {
  const border = {}
  for (const bor in borders) {
    if (borders[bor].color.indexOf('rgb') === -1) {
      border[luckyToExcelBorderCell.type[bor]] = {
        style: luckyToExcelBorderCell.style[borders[bor].style],
        color: { argb: borders[bor].color.replace('#', '') }
      }
    } else {
      border[luckyToExcelBorderCell.type[bor]] = {
        style: luckyToExcelBorderCell.style[borders[bor].style],
        color: { argb: borders[bor].color }
      }
    }
  }
  return border
}

function createCellPos(n) {
  const ordA = 'A'.charCodeAt(0)

  const ordZ = 'Z'.charCodeAt(0)
  const len = ordZ - ordA + 1
  let s = ''
  while (n >= 0) {
    s = String.fromCharCode((n % len) + ordA) + s

    n = Math.floor(n / len) - 1
  }
  return s
}

// 把RGB颜色转换为16进制颜色
function colorRGBtoHex(color) {
  var rgb = color.split(',');
  var r = parseInt(rgb[0].split('(')[1]);
  var g = parseInt(rgb[1]);
  var b = parseInt(rgb[2].split(')')[0]);
  var hex = "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
  return hex;
}
export  {exportExcel}